﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Nirvana
{
    /// <summary>
    /// 用于UI纹理 or Text 作倾斜的功能
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    [AddComponentMenu("Nirvana/UI/Effects/Skew")]
    public sealed class UISkew : BaseMeshEffect
    {
        public enum SkewMode
        {
            FullRect,
            TextArea
        }
        [SerializeField]
        private SkewMode skewMode;
        [SerializeField]
        private Vector2 lowerLeftOffset = Vector2.zero;
        [SerializeField]
        private Vector2 lowerRightOffset = Vector2.zero;
        [SerializeField]
        private Vector2 upperLeftOffset = Vector2.zero;
        [SerializeField]
        private Vector2 upperRightOffset = Vector2.zero;

#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            if(this.graphic != null)
            {
                this.graphic.SetVerticesDirty();
            }
        }
#endif

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!this.IsActive() || vh.currentVertCount <= 0)
            {
                return;
            }

            List<UIVertex> tempList = VertexLists.Get();
            vh.GetUIVertexStream(tempList);
            List<UIVertex> newlist = ModifyTextureVertexs(tempList);
            if (newlist != null)
            {
                vh.Clear();
                vh.AddUIVertexTriangleStream(newlist);
            }
            VertexLists.Set(newlist);
        }


        private List<UIVertex> ModifyTextureVertexs(List<UIVertex> _list)
        {
            int totalCount = _list.Count;
            Vector2 topLeft = Vector2.zero;
            Vector2 botRight = Vector2.zero;
            if (this.skewMode == SkewMode.FullRect)
            {
                RectTransform rectTransform = this.transform as RectTransform;
                Rect rect = rectTransform.rect;
                topLeft = new Vector2(rect.xMin, rect.yMax);
                botRight = new Vector2(rect.xMax, rect.yMin);
            }
            else
            {
                topLeft = _list[0].position;
                botRight = _list[_list.Count - 1].position;
                for (int i = 0; i < _list.Count; i++)
                {
                    if (_list[i].position.x < topLeft.x)
                    {
                        topLeft.x = _list[i].position.x;
                    }
                    if (_list[i].position.y > topLeft.y)
                    {
                        topLeft.y = _list[i].position.y;
                    }

                    if (_list[i].position.x > botRight.x)
                    {
                        botRight.x = _list[i].position.x;
                    }
                    if (_list[i].position.y < botRight.y)
                    {
                        botRight.y = _list[i].position.y;
                    }
                }

            }

            float distX = botRight.x - topLeft.x;
            float distY = topLeft.y - botRight.y;
            for (int i = 0; i < totalCount; i++)
            {
                UIVertex vertex = _list[i];
                float num =  (vertex.position.y - botRight.y) / distY;
                float num2 = 1 - num;
                float num3 =  (botRight.x - vertex.position.x) / distX;
                float num4 = 1 - num3;

                Vector3 offset = Vector3.zero;
                float num5 = (this.upperLeftOffset.y * num + this.lowerLeftOffset.y * num2) * num3;
                float num6 = (this.upperRightOffset.y * num + this.lowerRightOffset.y * num2) * num4;
                offset.y = num5 + num6;

                float num7 = (this.upperLeftOffset.x * num3 + this.upperRightOffset.x * num4) * num;
                float num8 = (this.lowerLeftOffset.x * num3 + this.lowerRightOffset.x * num4) * num2;
                offset.x = num7 + num8;
                vertex.position += offset;

                _list[i] = vertex;
            }


            return _list;
        }
    }

}
